/*
 * Copyright 2009 Eat Local Food, LLC
 * Copyright (c) 2007 osCommerce (this file was written after
 * code review of osCommerce).
 *
 * This file is part of gwtCommerce.
 *
 * gwtCommerce is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * gwtCommerce is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with gwtCommerce.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.elf.gwt.admin.client.components;

import java.util.HashMap;
import java.util.Iterator;

import com.elf.gwt.admin.client.AdminComponentController;
import com.elf.gwt.admin.client.subcomponents.EditOrderSubComponent;
import com.elf.gwt.common.client.access.RequestParameter;
import com.elf.gwt.common.client.callback.SubComponentCallback;
import com.elf.gwt.common.client.model.OrderMetaModel;
import com.elf.gwt.common.client.model.OrderModel;
import com.elf.gwt.common.client.subcomponent.CommonSubComponent;
import com.elf.gwt.common.client.utils.CommonUtils;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.InlineHTML;
import com.google.gwt.user.client.ui.InlineLabel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.HTMLTable.CellFormatter;

/**
 *
 */
public class EditOrderComponent extends JSONServerComponent
{	
	protected static final String[] widgetNamesStatus  = {"comment", "orderStatus", "notifyCustomer", "appendComment"};
	protected static final String[] widgetNamesDeleteProduct  = {"orderProductId"};
	protected static final String[] widgetNamesEditProduct  = {"orderProductId", "productId", "productQuantity", "productName", "productModel", "productPrice", "productWeight", "taxClassId"};
	protected static final String[] widgetNamesDeleteTotal  = {"orderTotalId"};
	protected static final String[] widgetNamesAddTotal  = {"totalTitle", "totalValue"};
	protected static final String[] widgetNamesAddCoupon  = {"coupon_code"};
	protected static final String[] widgetNamesEditAddress  = {"addressId", "telephone", "emailAddress"};
	protected static final String[] widgetNamesAddPayment = {"paymentComments", "paymentAmount"};
	protected static final String[] widgetNamesEditIntroduction = {"quoteIntroduction"};
	protected static final String[] widgetNamesDeleteTermAndCondition = {"tAndCId"};

	public static final String DETAILS = "DETAILS";
	public static final String INVOICE = "INVOICE";
	public static final String PACKING_SLIP = "PACKING_SLIP";
	public static final String EditCustomer = "EditCustomer";
	public static final String EditShipTo = "EditShipTo";
	public static final String EditBillTo = "EditBillTo";
	public static final String UpdateOrderHistory = "UpdateOrderHistory";
	public static final String DeleteOrder = "DeleteOrder";
	public static final String DeleteTotal = "DeleteTotal";
	public static final String AddTotal = "AddTotal";
	public static final String AddCoupon = "AddCoupon";
	public static final String DeleteProduct = "DeleteProduct";
	public static final String UpdateCatalogProductsToCurrentPricing = "UpdateCatalogProductsToCurrentPricing";
	public static final String EditProduct = "EditProduct";
	public static final String AddPayment = "AddPayment";
	public static final String InsertQuote = "InsertQuote";
	public static final String EditIntroduction = "EditIntroduction";
	public static final String DeleteTermAndCondition = "DeleteTermAndCondition";
	public static final String InsertTermAndCondition = "InsertTermAndCondition";

	protected int selectedGroupId = 0;
	protected int selectedOrderId = 0;
	protected int selectedCustomerId = 0;
	protected OrderMetaModel orderMetaModel;
	protected OrderModel orderModel;
	protected EditOrderSubComponent detailsSubComponent = null;

	public ProductSearchComponent productSearchComponent = null;
	public TermsAndConditionsComponent termsAndConditionsComponent = null;

	protected HashMap<String, Widget> elements = null;

	public String action = "";

	protected String currentType = DETAILS;
	InlineLabel detailsLabel = null;
	InlineLabel invoiceLabel = null;
	InlineLabel packingSlipLabel = null;
	Button backButton = null;
	Button deleteButton = null;

	EditOrderComponent(AdminComponentController controller, String stylePrefix)
	{
		super(controller, stylePrefix);
		setupTimer();
		elements = new HashMap<String, Widget>();
		orderModel = new OrderModel();

		detailsLabel = new InlineLabel("Details");
		detailsLabel.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event)
			{
				currentType = DETAILS;
				try {
					buildFromModel();
				}
				catch (Exception e) {}
			}
		});
		invoiceLabel = new InlineLabel("Invoice");
		invoiceLabel.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event)
			{
				currentType = INVOICE;
				try {
					buildFromModel();
				}
				catch (Exception e) {}
			}
		});
		packingSlipLabel = new InlineLabel("Packing Slip");
		packingSlipLabel.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event)
			{
				currentType = PACKING_SLIP;
				try {
					buildFromModel();
				}
				catch (Exception e) {}
			}
		});
		detailsLabel.setStyleName("TypeLabel");
		invoiceLabel.setStyleName("TypeLabel");
		packingSlipLabel.setStyleName("TypeLabel");

		deleteButton = new Button("delete", deleteHandler);
		deleteButton.addStyleName("ComponentLink");
		backButton = new Button("back", backHandler);
		backButton.addStyleName("ComponentLink");
	}

	public void additionalRequestParameters()
	{
		addRequestParameter(new RequestParameter ("orderId", selectedOrderId));
		addRequestParameter(new RequestParameter("action", action));
		if (action.equals(InsertQuote)) {

			addRequestParameter(new RequestParameter ("customerId", selectedCustomerId));
		}

		if (detailsSubComponent != null) {
			String[] widgetNames = null;

			HashMap<String, Widget> elements = detailsSubComponent.getElements();

			if (action.equals(UpdateOrderHistory)) widgetNames = widgetNamesStatus;
			else if (action.equals(DeleteProduct)) widgetNames = widgetNamesDeleteProduct;
			else if (action.equals(EditProduct)) widgetNames = widgetNamesEditProduct;
			else if (action.equals(DeleteTotal)) widgetNames = widgetNamesDeleteTotal;
			else if (action.equals(AddTotal)) widgetNames = widgetNamesAddTotal;
			else if (action.equals(AddCoupon)) widgetNames = widgetNamesAddCoupon;
			else if (action.equals(AddPayment)) widgetNames = widgetNamesAddPayment;
			else if (action.equals(EditCustomer) || action.equals(EditShipTo) || action.equals(EditBillTo)) widgetNames = widgetNamesEditAddress;
			else if (action.equals(EditIntroduction)) widgetNames = widgetNamesEditIntroduction;
			else if (action.equals(DeleteTermAndCondition)) widgetNames = widgetNamesDeleteTermAndCondition;

			if (widgetNames != null) {
				for (int i=0; i < widgetNames.length; i++) {
					String widgetName = widgetNames[i];
					Widget widget = elements.get(widgetName);
					String value = CommonUtils.getValue(widget);
					if (value != null) addRequestParameter(new RequestParameter(widgetName, value));
				}
			}

			if (action.equals(EditProduct)) {
				Iterator<String> iterElements = elements.keySet().iterator();
				while (iterElements.hasNext())
				{
					String key = iterElements.next();
					if (key.startsWith("attribute") || key.startsWith("download")) {
						Widget widget = elements.get(key);
						String value = CommonUtils.getValue(widget);
						if (value != null) addRequestParameter(new RequestParameter(key, value));
					}
				} 

				if (productSearchComponent != null) {
					elements = productSearchComponent.elements;
					Widget widget = elements.get("productId");
					if (widget != null) {
						String value = CommonUtils.getValue(widget);
						int productId = Integer.parseInt(value);
						if (productId > 0) {
							iterElements = elements.keySet().iterator();
							while (iterElements.hasNext())
							{
								String key = iterElements.next();
								widget = elements.get(key);
								value = CommonUtils.getValue(widget);
								if (value != null) addRequestParameter(new RequestParameter(key, value));
							} 
						}
					}
					productSearchComponent = null;
				}
			}

			else if (action.equals(InsertTermAndCondition)) {
				elements = termsAndConditionsComponent.elements;
				Iterator<String> iterElements = elements.keySet().iterator();
				while (iterElements.hasNext())
				{
					String key = iterElements.next();
					if (key.startsWith("select-") || key.startsWith("tAndCId-")) {
						Widget widget = elements.get(key);
						String value = CommonUtils.getValue(widget);
						if (value != null) addRequestParameter(new RequestParameter(key, value));
					} 
				}
			}
		}

		action = "";
	}

	protected void buildMetaModel(JSONObject jsonObject) throws Exception
	{
		orderMetaModel = new OrderMetaModel(jsonObject);
	}

	protected void buildModel(JSONObject jsonObject) throws Exception
	{
		orderModel.update(jsonObject);
	}

	public void buildFromModel() throws Exception
	{
		clear();

		packingSlipLabel.setVisible(orderModel.getStatusId() > -1);

		if (orderModel.getStatusId() > -1) invoiceLabel.setText("Invoice");
		else invoiceLabel.setText("Quote");

		HorizontalPanel buttonPanel = new HorizontalPanel();
		buttonPanel.setStyleName("ZButtons");

		buttonPanel.add(backButton);
		buttonPanel.add(new InlineHTML("&nbsp;&nbsp;"));
		buttonPanel.add(deleteButton);

		add(buttonPanel);

		add(new HTML("&nbsp;"));
		updateTypeDisplay();
		Grid typeGrid = new Grid(1,3);
		CellFormatter cf = typeGrid.getCellFormatter();
		typeGrid.setStyleName("TypeGrid");
		typeGrid.setWidget(0, 0, detailsLabel);
		typeGrid.setWidget(0, 1, invoiceLabel);
		typeGrid.setWidget(0, 2, packingSlipLabel);
		cf.setWordWrap(0, 0, false);
		cf.setWordWrap(0, 1, false);
		cf.setWordWrap(0, 2, false);
		add(typeGrid);
		add(new HTML("&nbsp;"));

		if (detailsSubComponent == null) detailsSubComponent = new EditOrderSubComponent(this, adminController, handle, subComponentCallback);
		detailsSubComponent.setType(currentType);
		detailsSubComponent.build();
		add(detailsSubComponent);

		//focusWidget = (FocusWidget)detailsSubComponent.getElements().get("comment");
		onBuilt();
	}

	public boolean updateFromHistoryParameters(String[] params)
	{
		selectedOrderId = 0;
		selectedCustomerId = 0;
		try {
			selectedGroupId = Integer.parseInt(params[1]);
			AccountsGroupComponent accountsGroupComponent = (AccountsGroupComponent) controller.getComponent("AccountsGroupComponent");
			accountsGroupComponent.setSelectedGroupModel(selectedGroupId);	
			accountsGroupComponent.setSelectedInGUI();
			adminController.getNavigationStackPanel().showStack(accountsGroupComponent.getIndex());	

			selectedOrderId = Integer.parseInt(params[2]);

			if (params.length > 3) {
				selectedCustomerId = Integer.parseInt(params[3]);
			}
		}
		catch (Exception e) {}

		return super.updateFromHistoryParameters(params);
	}

	public OrderMetaModel getOrderMetaModel() {
		return orderMetaModel;
	}

	public OrderModel getOrderModel() {
		return orderModel;
	}

	public void updateTypeDisplay() {
		if (currentType.equals(DETAILS)) {
			detailsLabel.addStyleName("TypeSelected");
			invoiceLabel.removeStyleName("TypeSelected");
			packingSlipLabel.removeStyleName("TypeSelected");
		}
		else if (currentType.equals(INVOICE)) {
			detailsLabel.removeStyleName("TypeSelected");
			invoiceLabel.addStyleName("TypeSelected");
			packingSlipLabel.removeStyleName("TypeSelected");

		}
		else if (currentType.equals(PACKING_SLIP)) {
			detailsLabel.removeStyleName("TypeSelected");
			invoiceLabel.removeStyleName("TypeSelected");
			packingSlipLabel.addStyleName("TypeSelected");
		}
	}

	protected SubComponentCallback subComponentCallback = 
		new SubComponentCallback() {

		public void onNavigate(CommonSubComponent subComponent) {
		}

		public void onSuccess(CommonSubComponent subComponent) {
			EditOrderSubComponent editOrderSubComponent = (EditOrderSubComponent)subComponent;
			action = editOrderSubComponent.getAction();
			build(true);
		}

		public void onError(CommonSubComponent subComponent, Throwable exception) {}
	};

	protected ClickHandler deleteHandler= new ClickHandler() {
		public void onClick(ClickEvent event)
		{
			String quest = "Delete Order?";
			if (orderModel.getStatusId() < 0) quest = "Delete Quote?";
			if (Window.confirm(quest)) {
				action = DeleteOrder;
				build(true);
			}
		}
	};

	protected ClickHandler backHandler= new ClickHandler() {
		public void onClick(ClickEvent event)
		{
			String history = "AccountsComponent--" + selectedGroupId + "--" + selectedCustomerId;
			onSelection(history);
		}
	};

	public void build(JSONValue jsonValue)
	throws Exception
	{
		super.build(jsonValue);
		if (orderModel.getId() == -1)
		{
			String history = "AccountsComponent--3";
			onSelection(history);
		}
	}
}
